/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2011-2017 BaiQianJinRong and/or its affiliates. All rights reserved.
 *
 */
package com.ityibai.spring.cloud.study1.service;

import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by panda on 2017/6/7.
 * Version : 1.0
 * Description : com.ityibai.spring.cloud.study1.service.ComputeResource
 */
@RestController
public class ComputeResource {

    private static final Logger log = LoggerFactory.getLogger(ComputeResource.class);

    private static HashMap<Integer, User> USER_CACHE = Maps.newHashMap();

    private static AtomicInteger ids = new AtomicInteger(6);

    private ReentrantLock lock = new ReentrantLock();

    {
        USER_CACHE.put(1, new User(1, "keyo", 19));
        USER_CACHE.put(2, new User(2, "panda", 18));
        USER_CACHE.put(3, new User(3, "lufei", 20));
        USER_CACHE.put(4, new User(4, "sanzhi", 22));
        USER_CACHE.put(5, new User(5, "namei", 23));
        USER_CACHE.put(6, new User(6, "luojie", 25));
    }

    @Autowired
    private DiscoveryClient discoveryClient;

    @RequestMapping(value = "/add")
    public Integer add(@RequestParam Integer a, @RequestParam Integer b) {
        ServiceInstance instance = discoveryClient.getLocalServiceInstance();
        Integer r = a + b;
        log.info("/add, host:" + instance.getHost() + ", service_id:" + instance.getServiceId() + ", result:" + r);
        return r;
    }

    @RequestMapping(value = "/user",
            method = RequestMethod.GET,
            consumes = MediaType.APPLICATION_JSON_VALUE,
            headers = "Accept=application/json"
    )
    public User user(@RequestBody User user) {
        return user;
    }

    @RequestMapping(value = "/user",
            method = RequestMethod.POST,
            headers = "Accept=application/json",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User create(@RequestBody User user) {
        user.setId(ids.incrementAndGet());
        lock.lock();
        try {
            USER_CACHE.put(user.getId(), user);
        } finally {
            lock.unlock();
        }
        return user;
    }

    @RequestMapping(value = "/user/{id}",
            method = RequestMethod.PUT,
            headers = "Accept=application/json",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User update(@PathVariable("id") Integer id, @RequestBody User user) {
        user.setId(id);
        lock.lock();
        try {
            USER_CACHE.put(id, user);
        } finally {
            lock.unlock();
        }
        return user;
    }

    @RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE,
            headers = "Accept=application/json",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User delete(@PathVariable("id") Integer id) {
        User user;
        lock.lock();
        try {
            user = USER_CACHE.remove(id);
        } finally {
            lock.unlock();
        }
        return user;
    }

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET,
            headers = "Accept=application/json",
            consumes = MediaType.APPLICATION_JSON_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public User find(@PathVariable("id") Integer id) {
        lock.lock();
        try {
            return USER_CACHE.get(id);
        } finally {
            lock.unlock();
        }
    }

    @RequestMapping(value = "/users", method = RequestMethod.GET,
    headers = "Accept=application/json",
    consumes = MediaType.APPLICATION_JSON_VALUE,
    produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public List<User> users() {
        lock.lock();
        try {
            return new ArrayList<>(USER_CACHE.values());
        } finally {
            lock.unlock();
        }

    }

}
